﻿using System.Collections;
using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class MetadataHelperFields : Declaration, IReadOnlyList<MetadataFieldOrReference>
{
    private SyntaxList<MetadataFieldOrReference>? _fields;

    internal MetadataHelperFields(SyntaxToken helperFieldsKeywordToken, SyntaxNode? parent) :
        base(SyntaxKinds.MetadataHelperFields,
            helperFieldsKeywordToken,
            NodeConverter.ToIdentifier(helperFieldsKeywordToken),
            parent)
    {
    }


    protected override bool WithoutNameIdentifier => true;


    public int Count => _fields?.Count ?? 0;


    public MetadataFieldOrReference this[int index] =>
        _fields == null ? throw new IndexOutOfRangeException(nameof(index)) : _fields[index];

    public IEnumerator<MetadataFieldOrReference> GetEnumerator()
    {
        return _fields?.GetEnumerator() ??
               Enumerable.Empty<MetadataFieldOrReference>().GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }


    public void AddField(MetadataField field)
    {
        _fields ??= new SyntaxList<MetadataFieldOrReference>();
        _fields.Add(new MetadataFieldOrReference(field));
        field.Parent = this;
    }


    public void AddReference(MetadataFieldReference reference)
    {
        _fields ??= new SyntaxList<MetadataFieldOrReference>();
        _fields.Add(new MetadataFieldOrReference(reference));
        reference.Parent = this;
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        base.AcceptVisitor(visitor);

        if (_fields != null && !visitor.IsFinished)
        {
            foreach (MetadataFieldOrReference field in _fields)
            {
                if (field.IsField)
                {
                    Accept(visitor, field.Field);
                }
                else
                {
                    Accept(visitor, field.Reference);
                }
            }
        }
    }
}


public static partial class NodeFactory
{
    public static MetadataHelperFields CreateMetadataHelperFields(SyntaxNode? parent,
        SyntaxToken helperFieldsKeywordToken)
    {
        Debug.Assert(helperFieldsKeywordToken.IsNode(SyntaxKinds.HelperFieldsKeywordToken));
        return new MetadataHelperFields(helperFieldsKeywordToken, parent);
    }
}